#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <unistd.h>  // 提供 fork()、execlp()
#include <stdlib.h>  // 提供 exit()
#include <err.h>
#include <stdio.h>

static Display *dpy;
static int scr;
static Window root;

static Window create_window(int x, int y, int w, int h, int b) {
  Window win;
  XSetWindowAttributes xwa;
  
  xwa.background_pixel = WhitePixel(dpy, scr);
  xwa.border_pixel = BlackPixel(dpy, scr);
  xwa.event_mask = ButtonPressMask | ButtonMotionMask | ButtonReleaseMask |
                   KeyPressMask | EnterWindowMask | LeaveWindowMask | 
                   FocusChangeMask;
  
  win = XCreateWindow(dpy, root, x, y, w, h, b, DefaultDepth(dpy, scr),
                      InputOutput, DefaultVisual(dpy, scr),
                      CWBackPixel | CWBorderPixel | CWEventMask, &xwa);
  return win;
}

static void run() {
  XEvent ev;
  while (XNextEvent(dpy, &ev) == 0) {
    switch (ev.type) {
    case ButtonPress:
      return;
    case KeyPress:
      return;
    case FocusIn:
      printf("focus in\n");
      // 发送 "focus in" 通知
      if (fork() == 0) {  // 创建子进程
        // 子进程中调用 notify-send
        execlp("notify-send", "notify-send", "焦点事件", "focus in", (char*)NULL);
        exit(1);  // 如果 execlp 失败，退出子进程
      }
      break;
    case FocusOut:
      printf("focus out\n");
      // 发送 "focus out" 通知
      if (fork() == 0) {  // 创建子进程
        execlp("notify-send", "notify-send", "焦点事件", "focus out", (char*)NULL);
        exit(1);  // 如果 execlp 失败，退出子进程
      }
      break;
    }
  }
}

int main(void) {
  Window win;
  Atom wm_take_focus;
  
  dpy = XOpenDisplay(NULL);
  if (dpy == NULL) {
    err(1, "ERROR: can not open display");
  }
  
  scr = XDefaultScreen(dpy);
  root = RootWindow(dpy, scr);
  win = create_window(500, 500, 500, 500, 25);

  wm_take_focus = XInternAtom(dpy, "WM_TAKE_FOCUS", False);
  XSetWMProtocols(dpy, win, &wm_take_focus, 1);

  XMapWindow(dpy, win);
  XSync(dpy, False);

  
  run();

  XUnmapWindow(dpy, win);
  XDestroyWindow(dpy, win);
  XCloseDisplay(dpy);

  return 0;
}
